package org.insia.smartposse.manager;

import java.io.Serializable;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

import org.hibernate.Session;
import org.insia.smartposse.form.ProjectForm;
import org.insia.smartposse.manager.iface.IManager;
import org.insia.smartposse.manager.list.JobsListManager;
import org.insia.smartposse.mapping.Categories;
import org.insia.smartposse.mapping.Projects;
import org.insia.smartposse.mapping.Users;
import org.insia.smartposse.mapping.dao.ProjectsDAO;

/**
 * Class of manage a Project
 *
 * @author cmougel
 *
 */
public final class ProjectManager implements Serializable, IManager {

	private final ProjectsDAO _dao;
	private final Projects _project;
	private Integer _remain = null;
	private final static String STRING_TO_DATE = "yyyy-MM-dd";

	/**
	 * Create a Project empty
	 *
	 */
	public ProjectManager(){
		_dao = new ProjectsDAO();
		_project = new Projects();
	}

	/**
	 * Create a Project with a POJO Project
	 */
	public ProjectManager(Projects project){
		_dao = new ProjectsDAO();
		_project = project;
	}

	/**
	 * Create a Project with a POJO Project
	 */
	public ProjectManager(Projects project, Session session){
		_project = project;
		_dao = new ProjectsDAO(session);
	}

	public ProjectManager(int i) {
		_dao = new ProjectsDAO();
		_project = _dao.get(i, _dao.getSession());
	}

	/**
	 * Construtor for save the Form in Project Manager
	 *
	 * @param form
	 * @throws ParseException
	 */
	public ProjectManager(ProjectForm form) throws ParseException {
		this();
		setManager(new UserManager(form.getManagerId()));
		setStartDate(form.getStartDate());
		setEndDate(form.getEndDate());
		setLocation(form.getLocation());
		setCompany(form.getCompany());
		setSubject(form.getSubject());
		setShortDescription(form.getShortDescription());
		setCategory(new CategorieManager(form.getCategoryId()));
	}






	/**
	 * Return the unique identifier of this class
     * @hibernate.id
     *  generator-class="increment"
     *  column="id"
     */
	public Integer getId () {
		return _project.getId();
	}

	/**
	 * Set the unique identifier of this class
	 * @param id the new ID
	 */
	public void setId (Integer id) {
		_project.setId(id);
	}




	/**
	 * Return the value associated with the column: budget
	 */
	public double getBudget () {
		return _project.getBudget();
	}

	/**
	 * Set the value related to the column: budget
	 * @param budget the budget value
	 */
	public void setBudget (double budget) {
		_project.setBudget(budget);
	}



	/**
	 * Return the value associated with the column: company
	 */
	public String getCompany () {
		return _project.getCompany();
	}

	/**
	 * Set the value related to the column: company
	 * @param company the company value
	 */
	public void setCompany (String company) {
		_project.setCompany(company);
	}



	/**
	 * Return the value associated with the column: complete
	 */
	public Boolean isComplete () {
		return _project.isComplete();
	}

	public Boolean getComplete(){
		return isComplete();
	}
	/**
	 * Set the value related to the column: complete
	 * @param complete the complete value
	 */
	public void setComplete (Boolean complete) {
		_project.setComplete(complete);
	}



	/**
	 * Return the value associated with the column: created_date
	 */
	public Date getCreatedDate () {
		return _project.getCreatedDate();
	}

	/**
	 * Set the value related to the column: created_date
	 * @param createdDate the created_date value
	 */
	public void setCreatedDate (Date createdDate) {
		_project.setCreatedDate(createdDate);
	}



	/**
	 * Return the value associated with the column: end_date
	 */
	public Date getEndDate () {
		if (_project.getEndDate().equals(new Date(0))){
			return null;
		} else {
			return _project.getEndDate();
		}
	}

	/**
	 * Set the value related to the column: end_date
	 * @param endDate the end_date value
	 */
	/*public void setEndDate (Date endDate) {
		_project.setEndDate(endDate);
	}*/

	public void setEndDate(String bday) throws ParseException {
		SimpleDateFormat sdf = new SimpleDateFormat(STRING_TO_DATE);
		_project.setEndDate(sdf.parse(getCorrectDate(bday)));
	}


	/**
	 * Return the value associated with the column: location
	 */
	public String getLocation() {
		return _project.getLocation();
	}

	/**
	 * Set the value related to the column: place
	 * @param place the place value
	 */
	public void setLocation (String location) {
		_project.setLocation(location);
	}



	/**
	 * Return the value associated with the column: short_description
	 */
	public String getShortDescription () {
		return _project.getShortDescription();
	}

	/**
	 * Set the value related to the column: short_description
	 * @param shortDescription the short_description value
	 */
	public void setShortDescription (String shortDescription) {
		_project.setShortDescription(shortDescription);
	}



	/**
	 * Return the value associated with the column: start_date
	 */
	public Date getStartDate () {
		if (_project.getStartDate().equals(new Date(0))){
			return null;
		} else {
			return _project.getStartDate();
		}
	}

	/**
	 * Set the value related to the column: start_date
	 * @param startDate the start_date value
	 */
	/*public void setStartDate (Date startDate) {
		_project.setStartDate(startDate);
	}*/

	public void setStartDate(String bday) throws ParseException {
		SimpleDateFormat sdf = new SimpleDateFormat(STRING_TO_DATE);
		_project.setStartDate(sdf.parse(getCorrectDate(bday)));
	}

	/**
	 * Return the value associated with the column: id
	 */
	public CategorieManager getCategory () {
		return new CategorieManager(_project.getCategoryId());
	}

	/**
	 * Set the value related to the column: id
	 * @param categoryId the id value
	 */
	public void setCategory (Categories categoryId) {
		_project.setCategoryId(categoryId);
	}

	/**
	 * Set the value related to the column: id
	 * @param categoryId the id value
	 */
	public void setCategory (CategorieManager categoryId) {
		_project.setCategoryId(categoryId.getCateory());
	}



	/**
	 * Return the value associated with the column: id
	 */
	public UserManager getManager () {
		return new UserManager(_project.getManagerId());
	}

	/**
	 * Set the value related to the column: id
	 * @param managerId the id value
	 */
	public void setManager (Users managerId) {
		_project.setManagerId(managerId);
	}

	/**
	 * Set the value related to the column: id
	 * @param managerId the id value
	 */
	public void setManager (UserManager managerId) {
		_project.setManagerId(managerId.getUser());
	}

	/**
	 * Define the Subject to Project
	 *
	 * @param subject
	 */
	public void setSubject(String subject){
		_project.setSubject(subject);
	}

	/**
	 *
	 * @return the Subject of Project
	 */
	public String getSubject(){
		return _project.getSubject();
	}

	/**
	 *
	 * @return Number of Job for this project
	 */
	public Integer getNbJob(){
		return _project.getJobProjectList().size();
	}

	/**
	 * Save or Update the project
	 */
	public void save() {

		// No NULL in database
		if (null == _project.getCompany()){
			_project.setCompany("");
		}

		if (null == _project.getCreatedDate()){
			_project.setCreatedDate(new Date());
		}

		if (null == _project.getEndDate()){
			_project.setEndDate(new Date(0));
		}

		if (null == _project.getStartDate()){
			_project.setStartDate(new Date(0));
		}

		if (null == _project.getLocation()){
			_project.setLocation("");
		}

		if (null == _project.getShortDescription()){
			_project.setShortDescription("");
		}

		if (null == _project.getSubject()){
			_project.setSubject("");
		}

		if (null == _project.getJobProjectList()){
			setComplete(false);
		}
		_dao.saveOrUpdate(_project);

	}

	/**
	 * Return the project save into ProjectManager
	 *
	 * @return
	 */
	public Projects getProject() {
		return _project;
	}

	/**
	 * Add a JobProject for this Project
	 *
	 * @param jobProject
	 */
	public void addJobProject(JobProjectManager jobProject) {
		if (null == jobProject.getJobProject().getFreelance()){
			setComplete(true);
		}
		_project.addToJobProjectList(jobProject.getJobProject());

	}

	/**
	 *
	 * @return The number of Job no accept by Manager
	 */
	public Integer getNbJobRemain(){
		nbJobRemain();
		return _remain;
	}

	/**
	 * Calcul the number of Job Remain
	 */
	private void nbJobRemain() {
		if (null == _remain ){
			_remain = _dao.getNbJobRemain(_project);
		}
	}

	/**
	 * Renseign if this Project had still job
	 *
	 * @return
	 */
	public Boolean getClose(){
		nbJobRemain();
		if (null == _remain){
			return false;
		}
		return (0 == _remain);
	}

	/**
	 * Return the list of Job For this project
	 *
	 * @return
	 */
	public JobsListManager getJobs(){
		return new JobsListManager(_project.getJobProjectList());
	}


	public String getCorrectDate(String s) {
		String regexpEn = "([0-9]{4})[/-]([0-9]{1,2})[/-]([0-9]{1,2})";
		String regexpFr = "([0-9]{1,2})[/-]([0-9]{1,2})[/-]([0-9]{4})";
		String ok = null;
		String[] arr = s.split("[/-]");
		if (s.matches(regexpEn)) {
			ok = arr[0] + "-" + arr[1] + "-"+ arr[2];
		}
		if (s.matches(regexpFr)) {
			ok = arr[2] + "-" + arr[1] + "-"+ arr[0];
		}
		return ok;
	}

}
